package server;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import server.mapper.Mapper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.*;

/**
 * Minicat的主类
 */
public class Bootstrap {

    //定义socket监听的端口号
    private int port=8080;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    /**
     * Minicat启动需要初始化展开的一些操作
     */
    public void start() throws Exception {


        //完成Minicat1.0版本
        // 浏览器请求http://localhost:8080,返回字符串到页面"Hello Minicat!"）
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("=========>>Minicat start on port :" + port);
//        while (true){
//            Socket socket = serverSocket.accept();
//            //有了socket 接收到请求
//            OutputStream outputStream = socket.getOutputStream();
//            String data = "你好Hello Minicat!";
//            String responseText = HttpProtocolUtil.getHttpHeader200(data.getBytes().length)+data;
//            outputStream.write(responseText.getBytes("GB2312"));
//            socket.close();
//        }

        /**
         * 完成Minicat2.0版本
         * 封装request和response对象，返回html静态资源文件
         */
        /*while (true){
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();

            //封装request对象和response对象
            Request request = new Request(inputStream);
            Response response = new Response(socket.getOutputStream());

            response.outPutHtml(request.getUrl());
            socket.close();
        }*/

        //加载解析配置文件 web.xml
        Map<String,HttpServlet> servletMap = new HashMap<String,HttpServlet>();


        //DealWebxml dealWebxml = new DealWebxml();
        //dealWebxml.loadServlet(servletMap);
        Mapper mapper = new Mapper();
        servletMap = mapper.initServer();
        /**
         * 完成Minicat3.0版本
         * 可以请求动态资源 servlet
         */
        /*while (true){
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();

            //封装request对象和response对象
            Request request = new Request(inputStream);
            Response response = new Response(socket.getOutputStream());

            if(servletMap.get(request.getUrl())==null){//静态资源
                response.outPutHtml(request.getUrl());
            }else {//动态资源servlet请求
                HttpServlet httpServlet = servletMap.get(request.getUrl());
                httpServlet.sevice(request,response);
            }

            socket.close();
        }*/


        /*
            不使用线程池，多线程改造
         */
        /*while (true){
            Socket socket = serverSocket.accept();
           RequestProcessor requestProcessor = new RequestProcessor(socket,servletMap);
           requestProcessor.start();
        }*/

        /*
            使用现线程池，多线程改造
         */
        //定义线程池
        System.out.println("============>>使用现线程池，多线程改造");
        int corePoolSize=10;
        int maximumPoolSize=50;
        long keepAliveTime=100l;
        TimeUnit unit=TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(50) ;
        ThreadFactory threadFactory=Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler
        );
        while (true){

            Socket socket = serverSocket.accept();
            RequestProcessor requestProcessor = new RequestProcessor(socket,servletMap);
            //requestProcessor.start();
            threadPoolExecutor.execute(requestProcessor);
        }


    }





    /**
     * Minicat的启动入口
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.start();
        }catch (IOException e){
            e.printStackTrace();
        }

    }


}
